<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>

    // this是什么？
    // this是一个指向对象的引用，指向调用函数的对象
    // 在全局作用域中，this指向全局对象（在浏览器中是window对象）
    // 在函数中，this指向调用该函数的对象
    // 在对象的方法中，this指向该对象

    // 在构造函数中，this指向新创建的对象
    // 新创建的对象是构造函数的实例
    // 在类的方法中，this指向实例对象

    // 在事件处理函数中，this指向触发事件的元素
    // 在setTimeout和setInterval中，this指向全局对象（在严格模式下为undefined）
    // 在ES6箭头函数中，this指向定义时的上下文，而不是调用时的上下文
    // 什么叫做上下文？上下文就是函数执行时的环境，包括函数的作用域、this指向的对象等
    // 例如：
    // function foo() {
    //   console.log(this)
    // }
    // foo() // 在全局作用域中调用，this指向全局对象（在浏览器中是window对象）
    // const obj = {
    //   name: 'Alice',
    //   foo: function() {
    //     console.log(this)
    //   }
    // }
    // obj.foo() // 在对象的方法中调用，this指向obj对象
    // const bar = obj.foo
    // bar() // 在函数中调用，this指向全局对象（在浏览器中是window对象）

    // 在类的方法中，this指向实例对象
    // 在DOM事件处理函数中，this指向触发事件的元素
    // 在setTimeout和setInterval中，this指向全局对象（在严格模式下为undefined）
    // 在ES6箭头函数中，this指向定义时的上下文，而不是调用时的上下文
    // 在类的方法中，this指向实例对象

  </script>
  <script>

    const obj = {
      name: '张三',
      sayHi() {
        const inner = () => {
          console.log(this.name);
        };
        inner(); // this 是 obj，因为箭头函数继承了 sayHi 的上下文
      }
    };
    obj.sayHi(); // 输出 张三

    const sayHi = obj.sayHi;
    sayHi(); // 输出 undefined，因为 this 指向了全局对象（在浏览器中是 window 对象）
    // 在严格模式下，输出 undefined，因为 this 是 undefined

  </script>
</body>

</html>